package com.ruoyi.webSocketMessage;

import com.alibaba.fastjson2.JSON;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author liu
 * @date
 * @ServerEndpoint
 */
@Component
@Slf4j
@ServerEndpoint(value = "/websocket")
public class WebSocketServer {
    /**
     * 某个客户端连接的session
     */
    private Session session;

    private static ConcurrentHashMap<String, Session> clientMap = new ConcurrentHashMap<>();

    /**
     * 建立连接后调用的方法
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        log.info("-----websocket成功连接------");
        this.session = session;
        clientMap.put(this.session.getId(), this.session);
        Map<String, Object> map = new HashMap<>();
        map.put("type", 1);
        map.put("sessionId", this.session.getId());
        WebSocketServer.sendToSpecClient(this.session.getId(), JSON.toJSONString(map));
    }

    /**
     * 处理客户端失败连接
     */
    @OnClose
    public void onClose() {
        clientMap.remove(this.session.getId());
        log.info("客户端失去连接,其sessionID为：" + this.session.getId());
    }

    /**
     * 连接报错时的处理方式
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("消息发生错误：" + session.getId());
        error.printStackTrace();
    }

    /**
     * 如果需要服务器接受客户端的消息就在这里写了
     *
     * @param text
     */
    @OnMessage
    public void onMessage(String text) {
        log.info("接受到客户端传来的消息：" + text);
    }

    /**
     * 推送消息
     * getAsyncRemote获取异步端点(推荐使用这个)
     * getBasicRemote获取阻塞端点（不推荐，如果第一次发送失败，就会一直阻塞，影响后面的进行）
     *
     * @param message
     */
    public static void sendMessage(String message) {
        // 遍历向所有用户发送消息
        clientMap.forEach((key, value) -> value.getAsyncRemote().sendText(message));
    }

    /**
     * 将消息发送给特定的用户
     */
    public static void sendToSpecClient(String clientId, String webSocketMessage) {
        if (clientMap.containsKey(clientId)) {
            clientMap.get(clientId).getAsyncRemote().sendText(webSocketMessage);
        } else {
            clientMap.remove(clientId);
            // throw new RuntimeException("特定用户消息发生错误，请稍后重试");
        }
    }


}